package org.xteam.box2text;

import org.eclipse.emf.common.util.EList;
import org.xteam.box2text.box.BoxPackage;
import org.xteam.box2text.box.Option;


public class Frame {
	
	public static final int DEFAULT_RIGHT_MARGIN = 79;
	
	private Point point;
	private int leftMargin;
	private int rightMargin;
	private int vs;
	private int hs;
	private int is;

	public Frame() {
		this(new Point(0,0), 0, DEFAULT_RIGHT_MARGIN, 1, 1, 2);
	}

	public Frame(Point point, int leftMargin, int rightMargin,
			int vs, int hs, int is) {
		this.point = point;
		this.leftMargin = leftMargin;
		this.rightMargin = rightMargin;
		this.vs = vs;
		this.hs = hs;
		this.is = is;
	}

	public Point point() {
		return point;
	}

	public Frame setRightMargin(int margin) {
		return new Frame(point, leftMargin, margin, vs, hs, is);
	}
	
	public Frame setLeftMargin(int margin) {
		return new Frame(point, margin, rightMargin, vs, hs, is);
	}
	
	public int getRightMargin() {
		return rightMargin;
	}
	
	public int getLeftMargin() {
		return leftMargin;
	}
	
	public int x() {
		return point.x();
	}

	public int y() {
		return point.y();
	}

	public Frame hsep(Point p, int hs) {
		if (point.isZero() && p.isZero()
				|| y() == p.y() && x() > p.x()
				|| y() > p.y())
			return this;
		return new Frame(new Point(p.x() + hs, p.y()), leftMargin, rightMargin, vs, this.hs, is);
	}
	
	public Frame vsep(Point p, int vs) {
		if (point.isZero() && p.isZero()
				|| y() == p.y() && x() > p.x()
				|| y() > p.y())
			return this;
		return new Frame(new Point(leftMargin, p.y() + vs), leftMargin, rightMargin, this.vs, hs, is);
	}

	public Frame setTs(EList<Option> eList) {
		int Ts = getTs(eList);
		if (Ts > 0) {
			return setLeftMargin(Ts);
		}
		return this;
	}

	public int getTs(EList<Option> options) {
		int value =lookup("ts", options, -1);
		return ensurePositive(value, 0);
	}
	
	public int getHs(EList<Option> options) {
		int value = lookup("hs", options, -1);
		return ensurePositive(value, hs);
	}

	public int getVs(EList<Option> options) {
		int value = lookup("vs", options, -1);
		return ensurePositive(value, vs);
	}
	
	public int getIs(EList<Option> options) {
		Option opt = lookup("is", options);
		if (opt == null)
			return is;
		int value = opt.getValue();
		if (value >= 0) {
			return value;
		}
		return - leftMargin;
	}
	
	private int lookup(String name, EList<Option> options, int def) {
		Option opt = lookup(name, options);
		if (opt != null)
			return opt.getValue();
		return def;
	}
	
	private Option lookup(String name, EList<Option> options) {
		for (Option opt : options) {
			if (opt.getName().equals(name)) {
				return opt;
			}
		}
		return null;
	}
	
	private int ensurePositive(int value, int def) {
		if (value >= 0) {
			return value;
		}
		return def;
	}

	public Frame setPoint(int x, int y) {
		return new Frame(new Point(x, y), leftMargin, rightMargin, vs, hs, is);
	}

}
